<?php
/**
 * 个人预约API - 适配现有数据库版本
 * 使用现有的数据库表：personal_reservations, museum_time_slots, museum_closure_dates 等
 */

header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization');

if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
    exit;
}

// 数据库配置
$dbConfig = [
    'host' => 'localhost',
    'name' => 'nzy_congqian_cn', 
    'user' => 'nzy_congqian_cn',
    'pass' => 'FsnXrDfDhm4wFJSX',
    'charset' => 'utf8mb4'
];

// 微信小程序配置
$wxConfig = [
    'appid' => 'wxf7a6dfca45112e43',
    'secret' => '36895ffe99019fd5498f4e3bf400f0a0'
];

// 数据库连接
try {
    $dsn = "mysql:host={$dbConfig['host']};dbname={$dbConfig['name']};charset={$dbConfig['charset']}";
    $pdo = new PDO($dsn, $dbConfig['user'], $dbConfig['pass']);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
    jsonResponse([
        'success' => false,
        'message' => '数据库连接失败: ' . $e->getMessage()
    ]);
}

// 响应函数
function jsonResponse($data) {
    echo json_encode($data, JSON_UNESCAPED_UNICODE);
    exit;
}

function success($data = null, $message = '操作成功') {
    jsonResponse([
        'code' => 200,
        'success' => true,
        'message' => $message,
        'data' => $data,
        'timestamp' => time()
    ]);
}

function error($message = '操作失败', $code = 400) {
    jsonResponse([
        'code' => $code,
        'success' => false,
        'message' => $message,
        'data' => null,
        'timestamp' => time()
    ]);
}

// 验证token
function verifyToken($token) {
    global $pdo;
    
    if (empty($token)) {
        return false;
    }
    
    // 移除Bearer前缀
    if (strpos($token, 'Bearer ') === 0) {
        $token = substr($token, 7);
    }
    
    try {
        $sql = "SELECT * FROM users WHERE token = ? AND token_expires > NOW() AND status = 'active'";
        $stmt = $pdo->prepare($sql);
        $stmt->execute([$token]);
        return $stmt->fetch(PDO::FETCH_ASSOC);
    } catch (Exception $e) {
        return false;
    }
}

// 获取当前用户
function getCurrentUser() {
    $token = getAuthToken();
    if (!$token) {
        error('需要登录', 401);
    }
    
    $user = verifyToken($token);
    if (!$user) {
        error('登录已过期，请重新登录', 401);
    }
    
    return $user;
}

// 获取认证token
function getAuthToken() {
    $headers = getallheaders();
    $authHeader = $headers['Authorization'] ?? $headers['authorization'] ?? '';
    
    if (strpos($authHeader, 'Bearer ') === 0) {
        return substr($authHeader, 7);
    }
    
    return $_GET['token'] ?? $_POST['token'] ?? '';
}

// 获取可预约时段
function getTimeSlots() {
    global $pdo;
    
    $date = $_GET['date'] ?? date('Y-m-d');
    
    // 验证日期格式
    if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $date)) {
        error('日期格式错误，请使用 YYYY-MM-DD 格式');
    }
    
    // 检查是否为未来30天内
    $today = date('Y-m-d');
    $maxDate = date('Y-m-d', strtotime('+30 days'));
    
    if ($date < $today) {
        error('不能预约过去的日期');
    }
    
    if ($date > $maxDate) {
        error('只能预约30天内的日期');
    }
    
    try {
        // 检查是否为闭馆日
        $closureSql = "SELECT * FROM museum_closure_dates 
                       WHERE closure_date = ? AND is_active = 1";
        $closureStmt = $pdo->prepare($closureSql);
        $closureStmt->execute([$date]);
        $closure = $closureStmt->fetch(PDO::FETCH_ASSOC);
        
        if ($closure) {
            success([
                'date' => $date,
                'is_closed' => true,
                'closure_reason' => $closure['reason'],
                'timeslots' => []
            ]);
            return;
        }
        
        // 获取活跃时段
        $slotSql = "SELECT * FROM museum_time_slots 
                    WHERE is_active = 1 
                    ORDER BY sort_order, start_time";
        $slotStmt = $pdo->query($slotSql);
        $slots = $slotStmt->fetchAll(PDO::FETCH_ASSOC);
        
        $timeslots = [];
        foreach ($slots as $slot) {
            // 计算该时段已预约人数
            $reservedSql = "SELECT COALESCE(SUM(visitor_count), 0) as total 
                           FROM personal_reservations 
                           WHERE visit_date = ? AND visit_time = ? AND status IN (0, 1)";
            $reservedStmt = $pdo->prepare($reservedSql);
            $reservedStmt->execute([$date, $slot['start_time']]);
            $reservedCount = $reservedStmt->fetch(PDO::FETCH_ASSOC)['total'];
            
            $availableCount = $slot['max_visitors'] - $reservedCount;
            
            $timeslots[] = [
                'id' => $slot['id'],
                'name' => $slot['slot_name'],
                'start_time' => substr($slot['start_time'], 0, 5), // HH:MM format
                'end_time' => substr($slot['end_time'], 0, 5),
                'max_visitors' => intval($slot['max_visitors']),
                'reserved_count' => intval($reservedCount),
                'available_count' => max(0, $availableCount),
                'is_available' => $availableCount > 0,
                'description' => $slot['slot_name']
            ];
        }
        
        success([
            'date' => $date,
            'is_closed' => false,
            'is_weekend' => date('N', strtotime($date)) >= 6,
            'timeslots' => $timeslots
        ]);
        
    } catch (Exception $e) {
        error('获取时段信息失败: ' . $e->getMessage(), 500);
    }
}

// 创建个人预约
function createReservation() {
    global $pdo;
    
    $user = getCurrentUser();
    $input = json_decode(file_get_contents('php://input'), true);
    
    // 验证必填字段
    $required = ['time_slot_id', 'visit_date', 'visitor_count', 'contact_name', 'contact_phone', 'visitors'];
    foreach ($required as $field) {
        if (empty($input[$field])) {
            error("缺少必填字段: $field");
        }
    }
    
    $timeSlotId = intval($input['time_slot_id']);
    $visitDate = $input['visit_date'];
    $visitorCount = intval($input['visitor_count']);
    $contactName = $input['contact_name'];
    $contactPhone = $input['contact_phone'];
    $specialRequirements = $input['special_requirements'] ?? '';
    $visitors = $input['visitors'] ?? [];
    
    // 验证参观者信息
    if (!is_array($visitors) || count($visitors) !== $visitorCount) {
        error('参观者信息数量与参观人数不匹配');
    }
    
    // 验证每个参观者的必填信息
    foreach ($visitors as $index => $visitor) {
        $visitorRequired = ['name', 'id_type', 'id_number'];
        foreach ($visitorRequired as $field) {
            if (empty($visitor[$field])) {
                error("第" . ($index + 1) . "位参观者缺少必填字段: $field");
            }
        }
        
        // 验证身份证号格式（如果是身份证）
        if ($visitor['id_type'] === 'id_card') {
            if (!preg_match('/^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/', $visitor['id_number'])) {
                error("第" . ($index + 1) . "位参观者身份证号格式不正确");
            }
        }
    }
    
    // 验证参数
    if ($visitorCount < 1 || $visitorCount > 10) {
        error('参观人数必须在1-10人之间');
    }
    
    if (!preg_match('/^1[3-9]\d{9}$/', $contactPhone)) {
        error('手机号格式不正确');
    }
    
    if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $visitDate)) {
        error('日期格式错误');
    }
    
    try {
        $pdo->beginTransaction();
        
        // 验证时段是否存在
        $slotSql = "SELECT * FROM museum_time_slots WHERE id = ? AND is_active = 1";
        $slotStmt = $pdo->prepare($slotSql);
        $slotStmt->execute([$timeSlotId]);
        $timeSlot = $slotStmt->fetch(PDO::FETCH_ASSOC);
        
        if (!$timeSlot) {
            throw new Exception('时段不存在或已禁用');
        }
        
        // 检查该用户当天是否已有预约
        $existingSql = "SELECT id FROM personal_reservations 
                       WHERE user_id = ? AND visit_date = ? AND status IN (0, 1)";
        $existingStmt = $pdo->prepare($existingSql);
        $existingStmt->execute([$user['id'], $visitDate]);
        
        if ($existingStmt->fetch()) {
            throw new Exception('您在该日期已有预约，请选择其他日期');
        }
        
        // 检查容量限制
        $reservedSql = "SELECT COALESCE(SUM(visitor_count), 0) as total 
                       FROM personal_reservations 
                       WHERE visit_date = ? AND visit_time = ? AND status IN (0, 1)";
        $reservedStmt = $pdo->prepare($reservedSql);
        $reservedStmt->execute([$visitDate, $timeSlot['start_time']]);
        $reservedCount = $reservedStmt->fetch(PDO::FETCH_ASSOC)['total'];
        
        if ($reservedCount + $visitorCount > $timeSlot['max_visitors']) {
            throw new Exception('该时段名额不足，剩余名额: ' . ($timeSlot['max_visitors'] - $reservedCount));
        }
        
        // 生成唯一预约码的函数
        function generateUniqueReservationCode($pdo, $userId, $visitDate, $visitorName) {
            $maxAttempts = 10;
            for ($i = 0; $i < $maxAttempts; $i++) {
                $code = strtoupper(substr(md5($userId . $visitDate . $visitorName . time() . rand(1000, 9999)), 0, 8));
                
                // 检查是否重复
                $checkSql = "SELECT COUNT(*) FROM reservations WHERE reservation_code = ?";
                $checkStmt = $pdo->prepare($checkSql);
                $checkStmt->execute([$code]);
                
                if ($checkStmt->fetchColumn() == 0) {
                    return $code;
                }
                
                // 如果重复，等待一毫秒再重试
                usleep(1000);
            }
            
            throw new Exception('无法生成唯一预约码，请稍后重试');
        }
        
        // 创建personal_reservations记录
        $insertSql = "INSERT INTO personal_reservations 
                     (user_id, visit_date, visit_time, visitor_count, contact_name, 
                      contact_phone, special_requirements, status, created_at, updated_at)
                     VALUES (?, ?, ?, ?, ?, ?, ?, 1, NOW(), NOW())";
        
        $insertStmt = $pdo->prepare($insertSql);
        $insertStmt->execute([
            $user['id'],
            $visitDate,
            $timeSlot['start_time'],
            $visitorCount,
            $contactName,
            $contactPhone,
            $specialRequirements
        ]);
        
        $personalReservationId = $pdo->lastInsertId();
        
        // 为每个参观者创建reservations表记录
        $reservationIds = [];
        $reservationCodes = [];
        $reservationSql = "INSERT INTO reservations 
                         (user_id, personal_reservation_id, reservation_type, visit_date, time_slot_id, visitor_count, 
                          visitor_name, visitor_phone, visitor_id_type, visitor_id_card, 
                          reservation_code, status, notes, created_at, updated_at)
                         VALUES (?, ?, 'personal', ?, ?, 1, ?, ?, ?, ?, ?, 'confirmed', ?, NOW(), NOW())";
        
        $reservationStmt = $pdo->prepare($reservationSql);
        
        foreach ($visitors as $visitor) {
            // 为每个参观者生成唯一预约码
            $reservationCode = generateUniqueReservationCode($pdo, $user['id'], $visitDate, $visitor['name']);
            $reservationCodes[] = $reservationCode;
            
            $reservationStmt->execute([
                $user['id'],
                $personalReservationId, // 关联个人预约ID
                $visitDate,
                $timeSlotId,
                $visitor['name'],
                $contactPhone, // 统一使用联系人手机号
                $visitor['id_type'],
                $visitor['id_number'],
                $reservationCode,
                $specialRequirements
            ]);
            $reservationIds[] = $pdo->lastInsertId();
        }
        
        $reservationId = $reservationIds[0]; // 返回第一个预约记录的ID
        
        $pdo->commit();
        
        success([
            'reservation_id' => $reservationId,
            'reservation_ids' => $reservationIds,
            'personal_reservation_id' => $personalReservationId,
            'reservation_codes' => $reservationCodes,
            'status' => 'confirmed',
            'timeslot_name' => $timeSlot['slot_name'],
            'visit_date' => $visitDate,
            'visit_time' => substr($timeSlot['start_time'], 0, 5),
            'visitor_count' => $visitorCount,
            'visitors' => array_map(function($visitor, $index) use ($reservationIds, $reservationCodes) {
                return [
                    'reservation_id' => $reservationIds[$index],
                    'reservation_code' => $reservationCodes[$index],
                    'name' => $visitor['name'],
                    'id_type' => $visitor['id_type'],
                    'id_number' => $visitor['id_number']
                ];
            }, $visitors, array_keys($visitors)),
            'message' => '预约成功，每位参观者请凭各自的预约码入馆参观'
        ], '预约成功');
        
    } catch (Exception $e) {
        $pdo->rollBack();
        error($e->getMessage());
    }
}

// 获取预约列表
function getReservationList() {
    global $pdo;
    
    $user = getCurrentUser();
    $page = max(1, intval($_GET['page'] ?? 1));
    $limit = min(50, max(1, intval($_GET['limit'] ?? 10)));
    $status = $_GET['status'] ?? '';
    $offset = ($page - 1) * $limit;
    
    try {
        // 构建查询条件
        $whereClause = "WHERE pr.user_id = ?";
        $params = [$user['id']];
        
        if ($status !== '') {
            $whereClause .= " AND pr.status = ?";
            $params[] = intval($status);
        }
        
        // 查询预约列表（包含预约码）
        $sql = "SELECT 
                    pr.*,
                    mts.slot_name,
                    mts.start_time,
                    mts.end_time,
                    GROUP_CONCAT(r.reservation_code ORDER BY r.id) as reservation_codes,
                    GROUP_CONCAT(r.visitor_name ORDER BY r.id) as visitor_names,
                    COUNT(r.id) as individual_reservations_count
                FROM personal_reservations pr
                LEFT JOIN museum_time_slots mts ON TIME(mts.start_time) = pr.visit_time
                LEFT JOIN reservations r ON pr.id = r.personal_reservation_id
                $whereClause 
                GROUP BY pr.id
                ORDER BY pr.created_at DESC 
                LIMIT $limit OFFSET $offset";
        
        $stmt = $pdo->prepare($sql);
        $stmt->execute($params);
        $reservations = $stmt->fetchAll(PDO::FETCH_ASSOC);
        
        // 获取总数
        $countSql = "SELECT COUNT(*) as total FROM personal_reservations pr $whereClause";
        $countStmt = $pdo->prepare($countSql);
        $countStmt->execute($params);
        $total = $countStmt->fetch(PDO::FETCH_ASSOC)['total'];
        
        // 处理数据格式
        $list = [];
        foreach ($reservations as $reservation) {
            $canCancel = false;
            if ($reservation['status'] == 0 || $reservation['status'] == 1) {
                $visitDateTime = $reservation['visit_date'] . ' ' . $reservation['visit_time'];
                $canCancel = strtotime($visitDateTime) > strtotime('+24 hours');
            }
            
            $statusMap = [0 => 'pending', 1 => 'confirmed', 2 => 'cancelled', 3 => 'rejected'];
            
            $list[] = [
                'id' => $reservation['id'],
                'timeslot_name' => $reservation['slot_name'] ?? '未知时段',
                'start_time' => substr($reservation['visit_time'], 0, 5),
                'end_time' => $reservation['end_time'] ? substr($reservation['end_time'], 0, 5) : '',
                'visit_date' => $reservation['visit_date'],
                'visitor_count' => intval($reservation['visitor_count']),
                'contact_name' => $reservation['contact_name'],
                'contact_phone' => $reservation['contact_phone'],
                'special_requirements' => $reservation['special_requirements'],
                'status' => $statusMap[$reservation['status']] ?? 'unknown',
                'can_cancel' => $canCancel,
                'reservation_codes' => $reservation['reservation_codes'] ? explode(',', $reservation['reservation_codes']) : [],
                'visitor_names' => $reservation['visitor_names'] ? explode(',', $reservation['visitor_names']) : [],
                'individual_reservations_count' => intval($reservation['individual_reservations_count']),
                'created_at' => $reservation['created_at'],
                'updated_at' => $reservation['updated_at'],
                // 为了兼容性，如果只有一个预约码，也提供单个字段
                'primary_reservation_code' => $reservation['reservation_codes'] ? explode(',', $reservation['reservation_codes'])[0] : null
            ];
        }
        
        success([
            'list' => $list,
            'pagination' => [
                'page' => $page,
                'limit' => $limit,
                'total' => intval($total),
                'pages' => ceil($total / $limit)
            ]
        ]);
        
    } catch (Exception $e) {
        error('获取预约列表失败: ' . $e->getMessage(), 500);
    }
}

// 获取预约详情
function getReservationDetail() {
    global $pdo;
    
    $user = getCurrentUser();
    $id = intval($_GET['id'] ?? 0);
    
    if (!$id) {
        error('预约ID不能为空');
    }
    
    try {
        $sql = "SELECT 
                    pr.*,
                    mts.slot_name,
                    mts.start_time,
                    mts.end_time
                FROM personal_reservations pr
                LEFT JOIN museum_time_slots mts ON TIME(mts.start_time) = pr.visit_time
                WHERE pr.id = ? AND pr.user_id = ?";
        
        $stmt = $pdo->prepare($sql);
        $stmt->execute([$id, $user['id']]);
        $reservation = $stmt->fetch(PDO::FETCH_ASSOC);
        
        if (!$reservation) {
            error('预约不存在', 404);
        }
        
        // 获取关联的预约码和参观者信息
        $reservationCodesSql = "SELECT 
                                   reservation_code,
                                   visitor_name,
                                   visitor_id_type,
                                   visitor_id_card,
                                   status as reservation_status
                               FROM reservations 
                               WHERE personal_reservation_id = ? 
                               ORDER BY id";
        $codesStmt = $pdo->prepare($reservationCodesSql);
        $codesStmt->execute([$id]);
        $individualReservations = $codesStmt->fetchAll(PDO::FETCH_ASSOC);
        
        $canCancel = false;
        if ($reservation['status'] == 0 || $reservation['status'] == 1) {
            $visitDateTime = $reservation['visit_date'] . ' ' . $reservation['visit_time'];
            $canCancel = strtotime($visitDateTime) > strtotime('+24 hours');
        }
        
        $statusMap = [0 => 'pending', 1 => 'confirmed', 2 => 'cancelled', 3 => 'rejected'];
        
        success([
            'id' => $reservation['id'],
            'timeslot_name' => $reservation['slot_name'] ?? '未知时段',
            'start_time' => substr($reservation['visit_time'], 0, 5),
            'end_time' => $reservation['end_time'] ? substr($reservation['end_time'], 0, 5) : '',
            'visit_date' => $reservation['visit_date'],
            'visitor_count' => intval($reservation['visitor_count']),
            'contact_name' => $reservation['contact_name'],
            'contact_phone' => $reservation['contact_phone'],
            'special_requirements' => $reservation['special_requirements'],
            'status' => $statusMap[$reservation['status']] ?? 'unknown',
            'can_cancel' => $canCancel,
            'review_note' => $reservation['review_note'],
            'individual_reservations' => $individualReservations,
            'reservation_codes' => array_column($individualReservations, 'reservation_code'),
            'visitor_names' => array_column($individualReservations, 'visitor_name'),
            'primary_reservation_code' => count($individualReservations) > 0 ? $individualReservations[0]['reservation_code'] : null,
            'created_at' => $reservation['created_at'],
            'updated_at' => $reservation['updated_at']
        ]);
        
    } catch (Exception $e) {
        error('获取预约详情失败: ' . $e->getMessage(), 500);
    }
}

// 取消预约
function cancelReservation() {
    global $pdo;
    
    $user = getCurrentUser();
    $id = intval($_GET['id'] ?? 0);
    
    if (!$id) {
        error('预约ID不能为空');
    }
    
    try {
        $pdo->beginTransaction();
        
        // 获取预约信息
        $sql = "SELECT * FROM personal_reservations WHERE id = ? AND user_id = ?";
        $stmt = $pdo->prepare($sql);
        $stmt->execute([$id, $user['id']]);
        $reservation = $stmt->fetch(PDO::FETCH_ASSOC);
        
        if (!$reservation) {
            throw new Exception('预约不存在');
        }
        
        if ($reservation['status'] == 2) {
            throw new Exception('预约已取消');
        }
        
        if ($reservation['status'] == 3) {
            throw new Exception('预约已被拒绝，无法取消');
        }
        
        // 检查是否可以取消（24小时前）
        $visitDateTime = $reservation['visit_date'] . ' ' . $reservation['visit_time'];
        if (strtotime($visitDateTime) <= strtotime('+24 hours')) {
            throw new Exception('距离预约时间不足24小时，无法取消');
        }
        
        // 更新personal_reservations状态为取消
        $updateSql = "UPDATE personal_reservations 
                     SET status = 2, updated_at = NOW() 
                     WHERE id = ?";
        $updateStmt = $pdo->prepare($updateSql);
        $updateStmt->execute([$id]);
        
        // 同时更新关联的reservations表记录
        $updateReservationsSql = "UPDATE reservations 
                                 SET status = 'cancelled', updated_at = NOW() 
                                 WHERE personal_reservation_id = ? AND user_id = ?";
        $updateReservationsStmt = $pdo->prepare($updateReservationsSql);
        $updateReservationsStmt->execute([$id, $user['id']]);
        
        $pdo->commit();
        
        success(null, '预约已成功取消');
        
    } catch (Exception $e) {
        $pdo->rollBack();
        error($e->getMessage());
    }
}

// 获取预约统计
function getReservationStats() {
    global $pdo;
    
    $user = getCurrentUser();
    
    try {
        $sql = "SELECT 
                    COUNT(*) as total_reservations,
                    SUM(CASE WHEN status = 0 THEN 1 ELSE 0 END) as pending_count,
                    SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END) as confirmed_count,
                    SUM(CASE WHEN status = 2 THEN 1 ELSE 0 END) as cancelled_count,
                    SUM(CASE WHEN status = 3 THEN 1 ELSE 0 END) as rejected_count,
                    SUM(visitor_count) as total_visitors
                FROM personal_reservations 
                WHERE user_id = ?";
        
        $stmt = $pdo->prepare($sql);
        $stmt->execute([$user['id']]);
        $stats = $stmt->fetch(PDO::FETCH_ASSOC);
        
        success([
            'total_reservations' => intval($stats['total_reservations']),
            'pending_count' => intval($stats['pending_count']),
            'confirmed_count' => intval($stats['confirmed_count']),
            'cancelled_count' => intval($stats['cancelled_count']),
            'rejected_count' => intval($stats['rejected_count']),
            'total_visitors' => intval($stats['total_visitors'])
        ]);
        
    } catch (Exception $e) {
        error('获取统计信息失败: ' . $e->getMessage(), 500);
    }
}

// 获取请求数据
function getRequestData() {
    $input = file_get_contents('php://input');
    if (!empty($input)) {
        return json_decode($input, true) ?: [];
    }
    return $_POST;
}

// 处理请求
$method = $_SERVER['REQUEST_METHOD'];
$action = $_GET['action'] ?? '';

try {
    switch ($method) {
        case 'GET':
            switch ($action) {
                case 'timeslots':
                    getTimeSlots();
                    break;
                case 'list':
                    getReservationList();
                    break;
                case 'detail':
                    getReservationDetail();
                    break;
                case 'stats':
                    getReservationStats();
                    break;
                default:
                    error('无效的操作');
            }
            break;
            
        case 'POST':
            switch ($action) {
                case 'create':
                    createReservation();
                    break;
                default:
                    error('无效的操作');
            }
            break;
            
        case 'PUT':
            switch ($action) {
                case 'cancel':
                    cancelReservation();
                    break;
                default:
                    error('无效的操作');
            }
            break;
            
        default:
            error('不支持的请求方法');
    }
    
} catch (PDOException $e) {
    error('数据库错误: ' . $e->getMessage(), 500);
} catch (Exception $e) {
    error('服务器错误: ' . $e->getMessage(), 500);
}
?>